package com.qq.service;

import com.qq.common.Message;
import com.qq.common.MessageType;
import com.qq.common.User;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;

/**
 * 功能：该类负责服务器和客户端的登录验证
 * 作者：可凡
 */
public class QQSeverService {
    private ServerSocket serverSocket;
    private Message message;
    private static final HashMap<String, User> usersMap = new HashMap<>();

    //使用静态代码块使其在类加载时就初始化集合
    static {
        usersMap.put("马可", new User("马可", "086511"));
        usersMap.put("周旺", new User("周旺", "123456"));
        usersMap.put("程泽烁", new User("程泽烁", "123456"));
        usersMap.put("占义民", new User("占义民", "123456"));
    }

    public boolean checkUser(String userId, String password) {
        User user = usersMap.get(userId);
        if (user == null) {
            return false;
        }
        return user.getPasswd().equals(password);
    }

    /**
     * 功能：该构造器负责判断登录账号密码是否正确并返回相应登录状态，
     * 登录成功时启动通信线程并添加到HashMap集合中。
     */
    public QQSeverService() {
        try {
            // 初始打印服务器监听信息
            String staticText = "服务器正在监听8888端口，等待连接中 ";
            System.out.print(staticText);
            serverSocket = new ServerSocket(8888);
            // 持续接收客户端消息
            while (true) {
                // 启动加载动画线程，动画始终在“服务器正在监听8888端口.....”这行后更新
                Thread loadingThread = new Thread(() -> {
                    String[] anim = {"|", "/", "-", "\\"};
                    int i = 0;
                    while (!Thread.currentThread().isInterrupted()) {
                        // 使用\r回车符重写整行：固定文本 + 动画字符
                        System.out.print("\r" + staticText + anim[i % anim.length]);
                        try {
                            Thread.sleep(250);
                        } catch (InterruptedException e) {
                            break;
                        }
                        i++;
                    }
                    // 当动画结束时，将光标移至下一行
                    System.out.println();
                });
                loadingThread.start();

                // 阻塞等待客户端连接
                Socket accept = serverSocket.accept();

                System.out.println("\n接收到客户端连接...");

                ObjectInputStream in = new ObjectInputStream(accept.getInputStream());
                User user = (User) in.readObject();
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(accept.getOutputStream());

                // 判断用户名和密码是否正确
                if (checkUser(user.getUserId(), user.getPasswd())) {
                    // 登录成功：设置消息类型并返回消息对象
                    message = new Message();
                    message.setMesType(MessageType.MESSAGE_LOGIN_SUCCEED);
                    objectOutputStream.writeObject(message);
                    objectOutputStream.flush();

                    // 启动处理该客户端的通信线程
                    ServerConnectClientThread serverConnectClientThread = new ServerConnectClientThread(accept, user.getUserId());
                    serverConnectClientThread.setName(user.getUserId());
                    serverConnectClientThread.start();
                    System.out.println("成功与用户：" + user.getUserId() + "建立通讯！");
                    ManageServerThread.addServer(user.getUserId(), serverConnectClientThread);
                } else {
                    // 登录失败：设置消息类型并返回消息对象
                    message = new Message();
                    message.setMesType(MessageType.MESSAGE_LOGIN_FAILED);
                    objectOutputStream.writeObject(message);
                    objectOutputStream.flush();
                    accept.close();
                }

                // 处理完一个连接后，再次输出监听提示文字（保持一致）
                System.out.print(staticText);
            }
        } catch (IOException e) {
            System.out.println("监听异常！" + e.getMessage());
        } catch (ClassNotFoundException e) {
            System.out.println("接收客户端消息时出现错误！" + e.getMessage());
        } finally {
            try {
                if (serverSocket != null) {
                    serverSocket.close();
                }
            } catch (IOException e) {
                System.out.println("监听服务关闭时出现异常！" + e.getMessage());
            }
        }
    }

}
